home *** CD-ROM | disk | FTP | other *** search
/ BCI NET / BCI NET Dec 94.iso / archives / programming / utilities / ninfo.lha / Ninfo / decode.c next >
Encoding:
C/C++ Source or Header  |  1992-05-21  |  20.9 KB  |  1,021 lines

  1. /* 68000 disassembler Version 1.2 */
  2. /* Amiga Version: A. F. Preston   */
  3. #include <stdio.h>
  4. #include "hunk.h"
  5. int      codedisp;         /* offset of code */
  6. int      codesize;         /* LENGTH OF CODE */
  7. char     *codeaddress;     /* ADDRESS OF CODE */
  8. short srckind;             /* source kind flag */
  9. char codes[] = "RASRHILSCCCSNEEQVCVSPLMIGELTGTLE";
  10. char *interpret[16] =
  11.   {
  12.   /*0*/ "\0\0\0\0\0\0\0\0",
  13.   /*1*/ "",
  14.   /*2*/ "",
  15.   /*3*/ "",
  16.   /*4*/ "\0\0\0\0\0\0\0\0",
  17.   /*5*/ "\170\170\170\104\173\173\173\104ADDQ\0S\0\0\0\0DB\0\0\0SUBQ\0\321\321\342",
  18.   /*6*/ "\360\360\360\360\360\360\360\360B",
  19.   /*7*/ "\200\200\200\200\200\200\200\200MOVEQ",
  20.   /*8*/ "\30\30\30\21\104\105\105\22OR\0\0\0DIVU\0DIVS\0SBCD\0\70\23\143\0\0\70\0\0",
  21.   /*9*/ "\30\30\30\50\102\102\102\50SUB\0\0SUBX\0\70\31\151",
  22.   /*a*/ "\0\0\0\0\0\0\0\0",
  23.   /*b*/ "\30\30\30\50\103\103\103\50CMP\0\0EOR\0\0CMPM\0\71\71\132",
  24.   /*c*/ "\30\30\30\21\105\106\107\22AND\0\0MULU\0MULS\0ABCD\0EXG\0\0\70\23\143\0\0\70\64\224\0\0\70\0\64",
  25.   /*d*/ "\30\30\30\50\102\102\102\50ADD\0\0ADDX\0\70\31\151",
  26.   /*e*/ "",
  27.   /*f*/ "\0\0\0\0\0\0\0\0"
  28.   };
  29.   struct op5_Q
  30.     {
  31.     unsigned opcode:4;
  32.     unsigned data  :3;
  33.     unsigned otype :1;
  34.     unsigned omode :2;
  35.     unsigned eamod :3;
  36.     unsigned eareg :3;
  37.     };
  38.   struct op5_cc
  39.     {
  40.     unsigned opcode:4;
  41.     unsigned ccode :4;
  42.     unsigned omode :2;
  43.     unsigned eamod :3;
  44.     unsigned eareg :3;
  45.     };
  46.   struct indexword
  47.     {
  48.     unsigned dora:1;
  49.     unsigned ireg:3;
  50.     unsigned size:1;
  51.     unsigned junk:3;
  52.     unsigned disp:8;
  53.     };
  54.  
  55. struct instruction
  56.   {
  57.   unsigned  opcode:4;
  58.   unsigned  destreg:3;
  59.   unsigned  extend:3;
  60.   unsigned  srcmode:3;
  61.   unsigned  srcreg:3;
  62.   };
  63. struct shiftbits
  64.   {
  65.   unsigned  opcode:4;
  66.   unsigned  count:3;
  67.   unsigned  direct:1;
  68.   unsigned  optype:2;
  69.   unsigned  opmode:1;
  70.   unsigned  shift:2;
  71.   unsigned  dest:3;
  72.   };
  73. struct testbits
  74.   {
  75.   unsigned  opcode:4;
  76.   unsigned  ccode:4;
  77.   unsigned  offset:8;
  78.   };
  79. struct mview 
  80.   {
  81.   unsigned  zero:1;
  82.   unsigned    di:3;
  83.   unsigned  type:1;
  84.   unsigned  size:1;
  85.   unsigned zeros:6;
  86.   unsigned    dh:4;
  87.   };
  88.  
  89. union
  90.   {
  91.   struct op5_Q       qview;
  92.   struct op5_cc      cview;
  93.   struct mview        bits;
  94.   struct instruction iview;
  95.   struct shiftbits       s;
  96.   struct testbits    tview;
  97.   short              sview;
  98.   } cheat;
  99. char opline[80];
  100. char  *hex;          /* output byte pointer */
  101. char  *opp;          /* output line pointer */
  102.  
  103. /* */
  104. void startline()    /* initialize the output line */
  105.   {
  106.   short i;
  107.   for(i=0; i < 80; i++)opline[i] = ' ';
  108.   opp = opline;
  109.   hex = &opline[17];   /* op code bytes start here */
  110.   }
  111.  
  112. void padd()     /* pad line to col 40 */
  113.   {
  114.   opp = &opline[45];   /* instruction codes start here */
  115.   }
  116.  
  117. void opchar(c)  /* put characters in output buffer */   
  118. char c;
  119.   {
  120.   *opp++=c;
  121.   }
  122.  
  123. void opstring(s) /* put string in output buffer */
  124. char *s;
  125.   {
  126.   while (*s!='\0') opchar(*s++);
  127.   }
  128.  
  129. short opcode(s)   /* output string with max of 5 characters */
  130. char *s;
  131.   {
  132.   short n=5;
  133.   while ( (*s!='\0') & (n-- >0) ) opchar(*s++);
  134.   return(n);   /* return the unused positions */
  135.   }
  136.  
  137. void opint(v)    /* output an integer recursively */
  138. unsigned int v;
  139.   {
  140.   unsigned int  t;
  141.   if ((t=v/10)>0) opint(t);
  142.   opchar( (char)(v%10+'0') );
  143.   }
  144.  
  145. void ophex(v,n)   /* output a value v, n digits long */
  146. unsigned int v;
  147. short n;
  148.   {
  149.   short sc;
  150.   char c;
  151.   while (n-- > 0)
  152.     {
  153.     sc = ( v >> ( n << 2 ) ) & 0xF;
  154.     c =  ( sc <= 9 ) ?  sc+'0'  :  sc-10+'A' ;
  155.     opchar( c );
  156.     };
  157.   }
  158.  
  159. void opbyte(v)   /* output a hex value v, 2 digits long */
  160. unsigned int v;
  161.   {
  162.   short sc;
  163.   short n=2;
  164.   while (n-- > 0)
  165.     {
  166.     sc = ( v >> ( n << 2 ) ) & 0xF;
  167.     *hex++ =  ( sc <= 9 ) ?  sc+'0'  :  sc-10+'A' ;
  168.     };
  169.   }
  170.  
  171. void lefthex(v,b)  /* output a value v(4 digits long), after b blanks */
  172. unsigned short  v;
  173. short b;
  174.   {
  175.   while (b-->0)opchar(' ');
  176.   ophex(v,4);
  177.   }
  178.  
  179. void invalid()    /* invalid opcode handler */
  180.   {
  181.   padd();
  182.   opstring(".WORD ");
  183.   ophex((unsigned int)cheat.sview,4);
  184.   }
  185.  
  186. void sourcekind(k)  /* output size indicator and set flag */
  187. short k;
  188.   {
  189.   opchar('.');
  190.   switch (k)
  191.     {
  192.     case 0: 
  193.     case 4:         
  194.       opchar('B'); 
  195.       srckind=0; 
  196.       break;
  197.     case 1: 
  198.     case 5: 
  199.     case 3: 
  200.       opchar('W'); 
  201.       srckind=1; 
  202.       break;
  203.     case 2:
  204.     case 6:
  205.     case 7:
  206.       opchar('L');
  207.       srckind=2;
  208.       break;
  209.     }
  210.   }
  211.  
  212.  
  213. unsigned char grabchar(n)
  214. short n;  /* leading blanks before output */
  215.   {
  216.   unsigned char c;
  217.   codesize--;
  218.   c = *codeaddress++;
  219.   while( n--> 0)*hex++ = ' ';  /* leading blanks */
  220.   opbyte(c);
  221.   return(c );  
  222.   }
  223.  
  224. short grabword(n)
  225. short n;           /* leading blanks for word */
  226.   {
  227.   short  *word;
  228.   unsigned char   byte[2];
  229.   word = (short *)byte;
  230.   byte[0] =  grabchar(n);
  231.   byte[1] =  grabchar(0);
  232.   return ( *word );
  233.   }
  234.  
  235. void outadd(address)
  236. char *address;
  237.   {
  238.   unsigned short *part;
  239.   int value;
  240.   if( codedisp != 0 )
  241.     { 
  242.     part  = (unsigned short *)&value;
  243.     part++; 
  244.     opchar('(');
  245.     value =  ((int)address - codedisp) & 0xFFFF;
  246.     lefthex(*part,0);
  247.     opchar(')');
  248.     };
  249.   part  = (unsigned short *)&value;
  250.   value =(int)address;
  251.   lefthex( *part++, 0);    /* output address */
  252.   lefthex( *part  , 0);
  253.   }  
  254.  
  255. void operand(mode,reg)     /* operand decoding */
  256. unsigned mode;
  257. unsigned reg;
  258.   {
  259.   union
  260.     {
  261.     short sh;
  262.     struct indexword ind;
  263.     }
  264.   mycheat;
  265.   short sloc;    /* byte or word offset */
  266.   long  cloc;    /* current address for branches */
  267.   opchar(' ');
  268.   switch (mode)
  269.     {
  270.     case 0: 
  271.       opchar('D');
  272.       opint(reg);
  273.       break;
  274.     case 1:
  275.       opchar('A');
  276.       opint(reg);
  277.       break;
  278.     case 2:
  279.       opstring("(A");
  280.       opint(reg);
  281.       opchar(')');
  282.       break;
  283.     case 3: 
  284.       opstring("(A");
  285.       opint(reg);
  286.       opstring(")+");
  287.       break;
  288.     case 4: 
  289.       opstring("-(A");
  290.      opint(reg);
  291.       opchar(')');
  292.       break;
  293.     case 5: 
  294.       opchar(' ');
  295.       ophex(grabword(1),4);
  296.       opstring("(A");
  297.       opint((unsigned int)reg);
  298.       opchar(')');
  299.       break;
  300.     case 6:
  301.       mycheat.sh = grabword(1);
  302.       ophex(mycheat.ind.disp,2);
  303.       opstring("(A");
  304.       opint(reg);
  305.       opchar(',');
  306.       opchar( (char)(mycheat.ind.dora==0 ? 'D' : 'A') );
  307.       opint(mycheat.ind.ireg);
  308.       opchar('.');
  309.       opchar( (char)(mycheat.ind.size==0 ? 'W' : 'L') );
  310.       opchar(')');
  311.       break;
  312.     case 7:
  313.      opchar(' ');
  314.       switch (reg)
  315.         {
  316.         case 0: 
  317.           cloc = grabword(1);
  318.           outadd( (char *)cloc );
  319.           break;
  320.         case 1:
  321.           cloc = grabword(1);
  322.           cloc = cloc<<16 | ( 0xFFFF & grabword(1));
  323.           outadd( (char *)cloc );
  324.           break;
  325.         case 2:    /* 16 bit offset value */
  326.           sloc = grabword(1);
  327.           opstring("   ");
  328.           cloc = (long)sloc + (long)codeaddress -2;
  329.           outadd( (char *)cloc );
  330.           break;
  331.         case 3:
  332.           mycheat.sh=grabword(1);
  333.           opstring(" + ");
  334.           ophex(mycheat.ind.disp,2);
  335.           opchar('(');
  336.           opchar( (char)(mycheat.ind.dora==0 ? 'D' : 'A') );
  337.           opint(mycheat.ind.ireg);
  338.           opchar('.');
  339.           opchar( (char)(mycheat.ind.size==0 ? 'W' : 'L') );
  340.           opchar(')');
  341.           break;
  342.       case 4: 
  343.         opstring("# ");
  344.         switch (srckind)
  345.           {
  346.           case 0:
  347.             ophex((unsigned int)grabword(1),2);
  348.             break;
  349.           case 1: 
  350.             ophex((unsigned int)grabword(1),4);
  351.             break;
  352.           case 2:
  353.             ophex((unsigned int)grabword(1),4);
  354.             ophex((unsigned int)grabword(0),4);
  355.             break;
  356.           };
  357.         break;
  358.       case 5:  /* 32 bit offset */
  359.         cloc = (long)grabword(1);
  360.         cloc = cloc<<16 | ( 0xFFFF & (long) grabword(1));
  361.         opstring("   ");
  362.         cloc = cloc + (long)codeaddress -4;
  363.         outadd( (char *)cloc );
  364.         break;
  365.       case 6:  /* 8 bit offset */ 
  366.         sloc = (short)(cheat.tview.offset) ;
  367.         opstring("   ");
  368.         cloc = (long)sloc + (long)codeaddress;
  369.         outadd( (char *)cloc );
  370.         break;
  371.  
  372.       }
  373.     }
  374.   }
  375.  
  376. void shiftinstruction()   /* handle shift instructions */
  377.   {
  378.   short n,t;
  379.   static char *mnemonics[8] =
  380.     {
  381.     "ASR",  "ASL",  "LSR", "LSL",
  382.     "ROXR", "ROXL", "ROR", "ROL"
  383.     } ;
  384.   padd();
  385.   if (cheat.s.optype==3)
  386.     {
  387.     n = opcode(mnemonics[(cheat.s.count<<1)+cheat.s.direct]);
  388.     while( n-- > 0)opchar(' ');
  389.     operand(cheat.iview.srcmode,cheat.iview.srcreg);
  390.     }
  391.   else
  392.     {
  393.     n = opcode(mnemonics[(cheat.s.shift<<1)+cheat.s.direct]);
  394.     sourcekind((short)cheat.s.optype);
  395.     while( n-- > 0)opchar(' ');
  396.     if (cheat.s.opmode==0)
  397.       {
  398.       opstring(" #");
  399.       opint((short) (t=cheat.s.count)==0 ? 8 : t );
  400.       }
  401.     else
  402.     operand(0,cheat.s.count);
  403.     opchar(',');
  404.     operand(0,cheat.s.dest);
  405.     }
  406.   }
  407.  
  408. void conditioncode(cc)
  409. unsigned short cc;
  410.   {
  411.   if (cc>1 || cheat.iview.opcode==6)
  412.     {
  413.     opchar(codes[cc<<1]);
  414.     opchar(codes[(cc<<1)+1]);
  415.     }
  416.   else if (cc==0) opchar('T');
  417.   else opchar('F');
  418.   }
  419.  
  420. void handlezero()
  421.   {
  422.   short ext =  cheat.iview.extend;
  423.   short dreg = cheat.iview.destreg;
  424.   short smod = cheat.iview.srcmode;
  425.   short sreg = cheat.iview.srcreg;
  426.   static char *opzero[] =
  427.     {
  428.     "ORI","ANDI","SUBI","ADDI","ERR","EORI","CMPI",""
  429.     }
  430.   ;
  431.   static char *opone[] =
  432.     {
  433.     "BTST","BCHG","BCLR","BSET"
  434.     }
  435.   ;
  436.   padd();
  437.   if ( (ext <= 2) & ( dreg != 4) )
  438.     {
  439.     opstring(opzero[dreg]);
  440.     sourcekind(ext);
  441.     operand(7,4);
  442.     opchar(',');
  443.     if ( (smod == 7) && (sreg == 4) )
  444.       {
  445.       if (srckind==0) 
  446.          {
  447.          opstring(" CCR ");
  448.          }
  449.       else opstring(" SR ");
  450.       }
  451.     else operand(smod,sreg);
  452.     }
  453.   else if ( (ext <= 3) & (dreg == 4) )
  454.     {
  455.     opstring(opone[ext]);
  456.     srckind = 0;
  457.     operand(7,4);
  458.     opchar(',');
  459.     operand(smod,sreg);
  460.     }
  461.   else if (ext>=4)
  462.     {
  463.     if (smod!=1)
  464.       {
  465.       opstring(opone[ext-4]);
  466.       operand(0,dreg);
  467.       opchar(',');
  468.       operand(smod,sreg);
  469.       }
  470.     else
  471.       {
  472.       opstring("MOVEP");
  473.       sourcekind(1+(ext&1));
  474.       if (ext<=5)
  475.         {
  476.         operand(5,sreg);
  477.         opchar(',');
  478.         operand(0,dreg);
  479.         }
  480.       else
  481.         {
  482.         operand(0,dreg);
  483.         opchar(',');
  484.         operand(5,sreg);
  485.         }
  486.       }
  487.     }
  488.   else if ( (ext <= 3) & (dreg == 7) )
  489.     {
  490.     opstring("MOVES");
  491.     sourcekind(ext);
  492.     operand(smod,sreg);
  493.     opchar(',');
  494.     operand(7,0);
  495.     }
  496.   else invalid();
  497.   }
  498.  
  499. void    breakfurther(base)
  500. char *base;
  501.   {
  502.   short ext =  cheat.iview.extend;
  503.   short dreg = cheat.iview.destreg;
  504.   short smod = cheat.iview.srcmode;
  505.   short sreg = cheat.iview.srcreg;
  506.   short comm,t, n;
  507.   padd();
  508.   
  509.   if ( ( (comm = *(base+ext) ) & 0xF0 ) == 0x40 )
  510.   comm = *(base + ( 8 + (t=comm&0xF) + (t<<2) 
  511.          + ( smod==0 ? 1 : (smod==1 ? 2 : 0) ) ) );
  512.   if (comm==0)invalid();
  513.   else
  514.     {
  515.     n = opcode( base + ( 8 + ( t = comm & 7 ) + (t<<2) ) );
  516.     if (comm & 8) sourcekind(ext);
  517.     if ( ( t = (comm>>4) & 0xF ) >= 13 )
  518.        {
  519.        conditioncode(cheat.tview.ccode);
  520.        n = 2;
  521.        };
  522.     while( n-- > 0) opchar(' ');
  523.     switch (t)
  524.       {
  525.       case 0:
  526.         invalid();
  527.         break;
  528.       case 1: 
  529.         operand(smod,sreg);
  530.         opchar(',');
  531.         operand(0,dreg);
  532.         break;
  533.       case 2:
  534.         operand(smod,sreg);
  535.         opchar(',');
  536.         operand(1,dreg);
  537.         break;
  538.       case 3:
  539.         operand(0,dreg);
  540.         opchar(',');
  541.         operand(smod,sreg);
  542.         break;
  543.       case 4:
  544.         opstring(" Internal check fail");
  545.         break;
  546.       case 5:
  547.         operand(3,sreg);
  548.         opchar(',');
  549.         operand(3,dreg);
  550.         break;
  551.       case 6:
  552.         operand(4,sreg);
  553.         opchar(',');
  554.         operand(4,dreg);
  555.         break;
  556.       case 7:
  557.         opstring(" #");
  558.         opint(dreg);
  559.         opchar(',');
  560.         operand(smod,sreg);
  561.         break;
  562.       case 8: 
  563.         opstring(" #");
  564.         ophex(cheat.tview.offset,2);
  565.         opchar(',');
  566.         operand(0,dreg);
  567.         break;
  568.       case 9:  
  569.         operand(1,dreg);
  570.         opchar(',');
  571.         operand(smod,sreg);
  572.         break;
  573.       case 13:
  574.         operand(smod,sreg);
  575.         break;
  576.       case 14:
  577.         operand(0,sreg);
  578.         opchar(',');
  579.         operand(7,2);
  580.         break;
  581.       case 15:
  582.         if     ( cheat.tview.offset == 0x00 ) operand(7,2);
  583.         else if( cheat.tview.offset == 0xFF ) operand(7,5); 
  584.         else                                  operand(7,6);
  585.         break;
  586.       }
  587.     }
  588.   }
  589.  
  590. void  moveinstruction(kind)
  591. unsigned short kind;
  592.   {
  593.   padd();
  594.   opstring("MOVE");
  595.   sourcekind(kind==1 ? 0 : (kind==2 ? 2 : 1));
  596.   operand(cheat.iview.srcmode,cheat.iview.srcreg);
  597.   opchar(',');
  598.   operand(cheat.iview.extend,cheat.iview.destreg);
  599.   }
  600.  
  601. void  startrange(bit)
  602. short bit;
  603.   {
  604.   operand(bit<=7 ? 0 : 1, bit%8);
  605.   }
  606.  
  607. void endrange(first,bit)
  608. short first,bit;
  609.   {
  610.   if (first<=7 && bit>7)
  611.     {
  612.     endrange(first,7);
  613.     opchar('/');
  614.     startrange(8);
  615.     first=8;
  616.     }
  617.   ;
  618.   if (bit>first)
  619.     {
  620.     opchar('-');
  621.     startrange(bit);
  622.     }
  623.   }
  624.  
  625. void  registerlist(kkkk,mask)
  626. short kkkk,mask;
  627.   {
  628.   short bit = 0;
  629.   short inrange = -1;
  630.   short some = 0;
  631.   while (bit <= 15)
  632.     {
  633.     if ( ( kkkk ? (mask>>(15-bit)) : (mask>>bit) ) & 1 )
  634.       {
  635.       if (inrange<0)
  636.         {
  637.         if (some) opchar('/');
  638.         startrange(bit);
  639.         some = 1; inrange = bit;
  640.         }
  641.       }
  642.     else
  643.       {
  644.       if (inrange>=0)
  645.         {
  646.         endrange(inrange,bit-1);
  647.         inrange = -1;
  648.         }
  649.       }
  650.     ;
  651.     bit++;
  652.     };
  653.   if (inrange>=0) endrange(inrange,15);
  654.   }
  655. void  specialbits()
  656.   {
  657.   short smod = cheat.iview.srcmode;
  658.   short sreg = cheat.iview.srcreg;
  659.   padd();
  660.   switch (smod)
  661.     {
  662.     case 0: 
  663.     case 1:
  664.       opstring("TRAP  #");
  665.       opint( ( (smod%1)<<3 ) + sreg );
  666.       break;
  667.     case 2:
  668.       opstring("LINK   ");
  669.       operand(1,sreg);
  670.       opchar(',');
  671.       srckind=1;
  672.       operand(7,4);
  673.       break;
  674.     case 3:
  675.       opstring("UNLK   ");
  676.       operand(1,sreg);
  677.       break;
  678.     case 4:
  679.       opstring("MOVE   ");
  680.       operand(1,sreg);
  681.       opstring(",USP");
  682.       break;
  683.     case 5:
  684.       opstring("MOVE    USP");
  685.       operand(1,sreg);
  686.       break;
  687.     case 6: 
  688.       switch (sreg)
  689.         {
  690.         case 0: 
  691.           opstring("RESET");
  692.           break;
  693.         case 1:
  694.           opstring("NOP");
  695.           break;
  696.         case 2:
  697.           opstring("STOP");
  698.           srckind=1;
  699.           operand(7,4);
  700.           break;
  701.         case 3:
  702.           opstring("RTE");
  703.           break;
  704.         case 4:
  705.           opstring("RTD");
  706.           srckind = 1;
  707.           operand(7,4);
  708.           break;
  709.         case 5:
  710.           opstring("RTS");
  711.           break;
  712.         case 6:
  713.           opstring("TRAPV");
  714.           break;
  715.         case 7:
  716.           opstring("RTR");
  717.           break;
  718.         } ;
  719.       break;
  720.     case 7: 
  721.       opstring("MOVEC   ");
  722.       srckind = 1;
  723.       operand(7,4);
  724.       break;
  725.     }
  726.   }
  727.  
  728. void  handlefour()
  729.   {
  730.   short ext =  cheat.iview.extend;
  731.   short dreg = cheat.iview.destreg;
  732.   short smod = cheat.iview.srcmode;
  733.   short sreg = cheat.iview.srcreg;
  734.   short reglist;
  735.   static char *unaryA[] =
  736.     {
  737.     "NEGX","CLR","NEG","NOT","ERR","TST"
  738.     };
  739.   static char *cross4[] =
  740.     {
  741.     "NBCD","PEA   ", "MOVEM.W","MOVEM.L",
  742.     "NBCD","SWAP  ","EXT.W  ","EXT.L   "
  743.     };
  744.   static char *jumps[] =
  745.     {
  746.     "JSR   ","JMP   "
  747.     };
  748.   static char * opty[] = { "MUL", "DIV"};
  749.   
  750.   padd();
  751.   if( dreg == 6 && ext <= 1)
  752.     {
  753.     opstring( opty[ext] );
  754.     cheat.sview = grabword(1);
  755.     opchar( (char)(cheat.bits.type == 0 ? 'U' : 'S') );
  756.     opstring(".L ");
  757.     operand(smod, sreg);
  758.     opchar(',');
  759.     if( cheat.bits.size == 0)
  760.       {
  761.       operand(0,cheat.bits.dh);
  762.       opchar(':');
  763.       operand(0,cheat.bits.di);
  764.       }
  765.     else   operand(0,cheat.bits.di);
  766.     }
  767.   else if (ext<=2 && (dreg<=3 || dreg==5))
  768.     {
  769.     opstring(unaryA[dreg]);
  770.     sourcekind(ext);
  771.     opchar(' ');
  772.     operand(smod,sreg);
  773.     }
  774.   else if (dreg==4 && ext<=3)
  775.     {
  776.     opstring(cross4[smod==0 ? ext+4 : ext]);
  777.     opchar(' ');
  778.     if (ext>=2 && smod!=0)
  779.       {
  780.       registerlist((short)(smod==4),grabword(1));
  781.       opchar(',');
  782.       };
  783.     operand(smod,sreg);
  784.     }
  785.   else if(ext==2 || ext==3)
  786.     {
  787.     if (dreg==6)
  788.       {
  789.       opstring(cross4[ext]);
  790.       opchar(' ');
  791.       reglist = grabword(1);
  792.       operand(smod==4 ? 3: smod ,sreg);
  793.       opchar(',');
  794.       registerlist(0,reglist);
  795.       }
  796.     else if (dreg==7)
  797.       {
  798.       opstring(jumps[ext-2]);
  799.       operand(smod,sreg);
  800.       }
  801.     else if (ext==3)
  802.       {
  803.       switch (dreg)
  804.         {
  805.         case 0:
  806.           opstring("MOVE  SR,  ");
  807.           operand(smod,sreg);
  808.           break;
  809.         case 1: 
  810.           opstring("MOVE  CCR, ");
  811.           operand(smod,sreg);
  812.           break;
  813.         case 2: 
  814.           opstring("MOVE  ");
  815.           srckind=0;
  816.           operand(smod,sreg);
  817.           opstring(", CCR");
  818.           break;
  819.         case 3: 
  820.           opstring("MOVE  ");
  821.           srckind=1;
  822.           operand(smod,sreg);
  823.           opstring(", SR");
  824.           break;
  825.         case 5: 
  826.           if( smod == 7  && sreg == 4 )
  827.             {
  828.             opstring("ILLEGAL");
  829.             }
  830.           else 
  831.             {
  832.             opstring("TAS  ");
  833.             operand(smod,sreg);
  834.             break;
  835.             };
  836.         }
  837.       }
  838.     }
  839.   else if (ext==7)
  840.     {
  841.     opstring("LEA    ");
  842.     operand(smod,sreg);
  843.     opchar(',');
  844.     operand(1,dreg);
  845.     }
  846.   else if (ext==6)
  847.     {
  848.     opstring("CHK    ");
  849.     srckind=1;
  850.     operand(smod,sreg);
  851.     opchar(',');
  852.     operand(0,dreg);
  853.     }
  854.   else if (ext==1 && dreg==7) specialbits();
  855.   else invalid();;
  856.   }
  857.  
  858. void op_5()
  859.   {
  860.   short ccod = cheat.cview.ccode;
  861.   short omop = cheat.qview.omode;
  862.   short qmod = cheat.qview.eamod;
  863.   short qreg = cheat.qview.eareg;
  864.   short qval = cheat.qview.data;
  865. /* op-code 5 is:                */
  866. /* TRAPcc, DBcc, and Scc if omop is 3 */
  867. /* ADDq and SUBq                      */
  868.   padd();
  869.   if( omop == 3 )
  870.     {
  871.     switch (qmod)
  872.       {
  873.       case 1: /* DBcc */
  874.         opstring("DB");
  875.         conditioncode(ccod);
  876.         opstring(".W ");
  877.         operand(0,qreg);
  878.         opchar(',');
  879.         operand(7,2);
  880.         break;
  881.       case 7: /* TRAPcc */
  882.         opstring("TRAP");
  883.         conditioncode(ccod);
  884.         if( qreg == 2 || qreg == 3 )
  885.           {
  886.           sourcekind(qreg-1);       /* size indicator */
  887.           operand(7,4);           /* immediate value*/
  888.           };
  889.         break;
  890.       default:
  891.         opstring("S");
  892.         conditioncode(ccod);
  893.         operand(qmod,qreg);
  894.       };
  895.     }
  896.   else
  897.     {
  898.     opstring( ( cheat.qview.otype == 0 ? "ADDQ" : "SUBQ") );
  899.     sourcekind(omop);
  900.     if( qval == 0 ) qval = 8;
  901.     opstring(" #");
  902.     opint(qval);
  903.     opchar(',');
  904.     operand(qmod, qreg);
  905.     };
  906.   }
  907. void 
  908. op_14()
  909.   {
  910.   short ext =  cheat.iview.extend;
  911.   short dreg = cheat.iview.destreg;
  912.   short smod = cheat.iview.srcmode;
  913.   short sreg = cheat.iview.srcreg;
  914. /* op-code 14 is:          */
  915. /* CMP  <ea>,Dn        if ext = 0, 1, or 2 */  
  916. /* CMPA <ea>,An        if ext = 3 or 7    */
  917. /* CMPM (Ax)+, (Ay)+   if ext = 4, 5, or 6 and smod = 1 */
  918. /* EOR  Dn, <ea>       if ext = 4, 5, or 6 and smod != 1 */
  919.   padd();
  920.   switch ( ext )
  921.     {
  922.     case 0:
  923.     case 1:       /* Compare */
  924.     case 2:
  925.       opstring("CMP");
  926.       sourcekind(ext);
  927.       opchar(' ');
  928.       operand(smod,sreg);
  929.       opstring(", ");
  930.       operand(0,dreg);
  931.       break;
  932.     case 3:      /* Compare address */
  933.     case 7: 
  934.       opstring("CMPA");
  935.       sourcekind(ext);
  936.       operand(smod,sreg);
  937.       opstring(", ");
  938.       operand(1,dreg);
  939.       break;
  940.     case 4:
  941.     case 5:      /* Compare Memory or Exclusive OR */
  942.     case 6:
  943.       if( smod == 1 ) 
  944.         {
  945.         opstring("CMPM");
  946.         sourcekind(ext);
  947.         operand(3,sreg);
  948.         opstring(", ");
  949.         operand(3,dreg);
  950.         }
  951.       else
  952.         {
  953.         opstring("EOR");
  954.         sourcekind(ext);
  955.         opchar(' ');
  956.         operand(0,dreg);
  957.         opstring(", ");
  958.         operand(smod,sreg);
  959.         };
  960.       break;
  961.     };
  962.   }
  963. void decode()         /* decode instructions at address */
  964.   {
  965.   startline();                /* initialize the line  */
  966.   outadd(codeaddress);      /* display address with offset */
  967.   cheat.sview=grabword(1);  /* get the opcode */
  968.   switch (cheat.iview.opcode)
  969.     {
  970.     case 1:
  971.     case 2:
  972.     case 3:
  973.       moveinstruction(cheat.iview.opcode);
  974.       break;
  975.     case 0:
  976.       handlezero();
  977.       break;
  978.     case 4:
  979.       handlefour();
  980.       break;
  981.     case 5:
  982.       op_5();
  983.       break;
  984.     case 6:
  985.     case 7:
  986.     case 8:
  987.     case 9:
  988.     case 10:
  989.       breakfurther(interpret[cheat.iview.opcode]);
  990.       break;
  991.     case 11:
  992.       op_14();
  993.       break;
  994.     case 12:
  995.     case 13:
  996.     case 15: 
  997.       breakfurther(interpret[cheat.iview.opcode]);
  998.       break;
  999.     case 14:
  1000.       shiftinstruction();
  1001.       break;
  1002.     } ;
  1003.   }
  1004.  
  1005. char * dumpcode(offset,loc,n)
  1006. int  offset;   /* relative offset for listings */
  1007. char *loc;     /* address of code */
  1008. int n;         /* length of code in bytes*/
  1009.   {
  1010.   codedisp = offset;
  1011.   codesize = n;
  1012.   codeaddress = loc;
  1013.   while (codesize>0)
  1014.     {
  1015.     decode();        /* disassemble */
  1016.     opchar(0x00);    /* null */
  1017.     puts(opline);
  1018.     };
  1019.   return(codeaddress);
  1020.   }
  1021.